<template>
  <div class="search-suggestion">
    <van-cell v-for="(item, index) in suggestion" :key="index" icon="search" @click="$emit('search',item)">
      <template #title>
        <span v-html="highlight(item)"></span>
      </template>
    </van-cell>
  </div>
</template>

<script>
import { getSearchSuggestionsAPI } from '../../../api/index.js'
import { debounce } from 'loadsh'
export default {
  name: 'SearchSuggestion',
  props: {
    searchText: {
      type: String,
      default: ''
    }
  },
  data () {
    return {
      suggestion: [] // 联想建议数据列表
    }
  },
  watch: {
    searchText: {
      // 首次监视触发
      immediate: true,
      // 监视的处理函数
      // debounce 防抖操作第一个参数必须是普通函数类型,不可以是箭头函数,因为兼有函数没有函数作用域会影响this的指向
      handler: debounce(function (newVal) {
        // 调用查询方法
        this.loadSearchSuggestion(newVal)
      }, 400)
    }
  },
  methods: {
    // 调用查询数据的接口
    async loadSearchSuggestion (val) {
      try {
        const { data: res } = await getSearchSuggestionsAPI(val)
        // 有时候后端会返回一个[null] 或者 [], 可以主动将这两种情况给成searchText的值
        if (res.data.options.length === 0 || res.data.options[0] === null) {
          // 如果数组中没有值,或者只有一个元素为null时
          res.data.options[0] = this.searchText
        }
        this.suggestion = res.data.options
      } catch {
        this.$toast('获取失败')
      }
    },
    /*
  目标2：联想建议列表中的每一个选项，都需要用富文本的形式进行高亮显示
  1. 通过v-html指令来实现高亮
  2. ABCDABCDABCD => 将里面的A全部变成 <span style="color: red;">A</span>
    2.1 replace 去替换字符串中的A
    replace(/A/gi) 通过正则匹配所有的A进行替换
    replaceAll(A) 替换所有的A
    2.2 indexOf， findIndex 获取索引，更具索引去替换splice
    2.3 split(将字符串变成数组) => 将符合查询要求的A 变成数组中元素分隔的`,` 然后用join将`,` 转化成拼接每个元素的字符串
    ABCDABCDABCD => [ , BCD, BCD, BCD] => <span style="color: red;">A</span>BCD<span style="color: red;">A</span>BCD<span style="color: red;">A</span>BCD
*/
    // 高亮展示数据处理方法
    highlight (val) {
      const highlightStr = `<span style="color: red;">${this.searchText}</span>`
      // 方案一
      //   const tempStr = val.replaceAll(this.searchText, highlightStr)
      // 方案二
      return val.split(this.searchText).join(highlightStr)
      // 方案三
      // 正则表达式
      // 中间的内容都会当作匹配字符来使用，而不是数据变量
      // 如果需要根据数据变量动态的创建正则表达式，则手动 new RegExp
      // RegExp 正则表达式构造函数
      //    参数1：匹配模式字符串，它会根据这个字符串创建正则对象
      //    参数2：匹配模式，要写到字符串中
      // const reg = new RegExp(this.searchText, 'gi')
      // return val.replace(reg, highlightStr)
    }
  }
}
</script>

<style lang="less" scoped>
</style>
